from twisted.internet import reactor
from core.websocket import WebSocketHandler, WebSocketSite
from twisted.web.static import File
import json
from core.base import ProtocalPool
from messages import ProtocalTypes,GetCompanyMessage,GetProjectsMessage,GetEmployeesMessage,GetDeliveriesMessage,AddProjectMessage
from handlers import GetCompanyHandler,GetProjectsHandler,GetEmployeesHandler,GetDeliveriesHandler,GetDishesHandler,AddProjectHandler
from biz.messages import GetDishesMessage
from core.threadpool import ThreadPool,Task
import atexit
from core.memcache import CacheManager
from threading import Thread
import time
from persist.daos import companyDao
from persist.cachedaos import CompanyCacheDao

class Deliveryhandler(WebSocketHandler):

    threadExecutor = ThreadPool(10)
    protocalPool = ProtocalPool()
    protocalPool.register(ProtocalTypes.GetCompany,GetCompanyMessage,GetCompanyHandler())
    protocalPool.register(ProtocalTypes.GetProjects,GetProjectsMessage,GetProjectsHandler())
    protocalPool.register(ProtocalTypes.GetProjectEmployees,GetEmployeesMessage,GetEmployeesHandler())
    protocalPool.register(ProtocalTypes.GetDeliveries,GetDeliveriesMessage,GetDeliveriesHandler())
    protocalPool.register(ProtocalTypes.GetDeliveryDishes,GetDishesMessage,GetDishesHandler())
    protocalPool.register(ProtocalTypes.AddProject,AddProjectMessage,AddProjectHandler())

    def frameReceived(self, frame):
        print frame;
        msg = json.loads(frame,encoding="utf-8");
        if(not msg or not msg['type']) :
            return;
        protocal = Deliveryhandler.protocalPool.getProtocal(msg['type'])
        protocal.read(msg['data']);
        handler = Deliveryhandler.protocalPool.getHandler(msg['type'])
        task = Task(handler.process,protocal,self.transport)
        Deliveryhandler.threadExecutor.processTask(task)

    def connectionMade(self):
        print 'connection comes'

    def connectionLost(self, reason):
        pass
    
    @staticmethod
    def shutdown():
        Deliveryhandler.threadExecutor.shutdown()

class DeliveryServer:
    
    def __init__(self):
        self.reactor = reactor
        self.initServer()
        self.registerShutdownHook()
        self.initMemCache()
    
    def initServer(self):
        root = File('.')
        site = WebSocketSite(root)
        site.addHandler('/delivery', Deliveryhandler)
        self.reactor.listenTCP(8001, site)

    def registerShutdownHook(self):
        atexit.register(self.shutdown)

    def initMemCache(self):
        self.cache = CacheManager(self.reactor,"localhost",11212)

    def startServer(self):
        self.reactor.run()

    def shutdown(self):
        Deliveryhandler.shutdown()

def main():
    server = DeliveryServer()
    #test()
    server.startServer()

def test():
    thread = Thread(target=__test)
    thread.start()

def __test():
    time.sleep(2)
    dao = CompanyCacheDao(companyDao)
    dao.getCompany(printCompany)

def printCompany(company):
    print company